﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Web;
using UtilsLib.UtilsLog;
using System.Drawing.Text;
using System.Net;

namespace UtilsLib.UtilsImage
{
    public class ImageUtility
    {
        /// <summary>
        /// Crop de l'image. Si startY et StartX = 0, le crop est centré
        /// </summary>
        /// <param name="imgPath">Output path after crop</param>
        /// <param name="size"> size of the crop</param>
        /// <param name="startX">Left position of the crop</param>
        /// <param name="startY">Top position of the crop</param>
        /// <returns></returns>
        public static Image CropImage(string imgPath, Size size)
        {
            return CropImage(Image.FromFile(imgPath), size, 0, 0);
        }
        public static Image CropImage(Image img, Size size)
        {
            return CropImage(img, size, 0, 0);
        }
        public static Image CropImage(string imgPath, Size size, int startX, int startY)
        {
            return CropImage(Image.FromFile(imgPath), size, startX, startY);
        }
        public static Image CropImage(Image img, Size size, int startX, int startY)
        {
            float height = size.Height;
            float width = size.Width;

            float ratio = 0F;

            ratio = height > width ? height / width : width / height;
            //check the image height & width against our desired image height
            if (height > img.Height)
            {
                height = img.Height;
                width = height / ratio;
            }
            if (width > img.Width)
            {
                width = img.Width;
                height = width / ratio;
            }
            //Crop starting at center point by default
            if (startX == 0 && startY == 0)
            {
                startX = (int)(img.Width - width) / 2;
                startY = (int)(img.Height - height) / 2;
            }

            Bitmap b = null;
            try
            {
                //create a bitmap window for cropping
                b = new Bitmap(img);
                // Clone a portion of the Bitmap object.

                Rectangle cloneRect = new Rectangle(startX, startY, (int)--width, (int)--height);

                if (IntPtr.Size == 8) //systèmes 64bits
                {
                    b = b.Clone(cloneRect, b.PixelFormat);
                }
                else //if (IntPtr.Size == 4) -> 32bits
                {
                    b.SetResolution(72F, 72F);
                    b = b.Clone(cloneRect, PixelFormat.Format24bppRgb);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                LogToFile.WriteException(e, "UtilsLib Crop Error : ");
                b.Dispose();
            }
            GC.Collect();
            return b;
        }

        /// <summary>
        /// Redimenssionement d'une image sans la déformer
        /// </summary>
        /// <param name="imgToResize">Image à redimensionner</param>
        /// <param name="size">nouvelle taille de l'image</param>
        /// <param name="isMaxSize">La taille voulue est la taille maximale</param>
        /// <returns></returns>
        /// 
        public static Image ResizeImage(string imgPath, Size size, bool isMaxSize = true)
        {
            return ResizeImage(Image.FromFile(imgPath), size, isMaxSize);
        }
        public static Image ResizeImage(Image imgToResize, Size size, bool isMaxSize = true)
        {
            Bitmap b;

            int sourceWidth = imgToResize.Width,
                sourceHeight = imgToResize.Height;

            int destX = 0,
                destY = 0;

            float nPercent = 0;
            float nPercentW = 0;
            float nPercentH = 0;

            nPercentW = ((float)size.Width / (float)sourceWidth);
            nPercentH = ((float)size.Height / (float)sourceHeight);

            if (isMaxSize)
                nPercent = (nPercentH < nPercentW) ? nPercentH : nPercentW;
            else
                nPercent = (nPercentH > nPercentW) ? nPercentH : nPercentW;

            //destX = Convert.ToInt32(((sourceWidth * nPercent) - size.Width) / 2);
            //destY = Convert.ToInt32(((sourceHeight * nPercent) - size.Height) / 2);



            if (nPercent > 1)
                nPercent = 1;

            //destX = (int)(size.Width - (sourceWidth * nPercent)) / 2;
            //destY = (int)(size.Height - (sourceHeight * nPercent)) / 2;

            int destWidth = (int)(sourceWidth * nPercent);
            int destHeight = (int)(sourceHeight * nPercent);

            //destX = Convert.ToInt32((size.Width - destWidth) / 2);
            //destY = Convert.ToInt32((size.Height - destHeight) / 2);

            b = new Bitmap(destWidth, destHeight);
            using (Graphics g = Graphics.FromImage((Image)b))
            {
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.SmoothingMode = SmoothingMode.HighQuality;
                g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                g.CompositingQuality = CompositingQuality.HighQuality;
                g.DrawImage(imgToResize, destX, destY, destWidth, destHeight);
            }

            return b;
        }

        /// <summary>
        /// Sauvegarde une image dans un fichier spécifique
        /// </summary>
        /// <param name="directoryName">Répertoire où sauver le fichier</param>
        /// <param name="fileName">Nom du fichier</param>
        /// <param name="img">Objet System.Drawing.Image</param>
        /// <param name="deleteIfExists">Suppression du fichier s'il existe déjà</param>
        public static void ImageSave(string directoryName, string fileName, Image img, ImageFormat imgFormat, bool deleteIfExists = true)
        {
            ImageCodecInfo jpegCodec = ImageCodecInfo.GetImageEncoders().Where(enc => enc.FormatID == imgFormat.Guid).ToArray().First();

            if (!Directory.Exists(@directoryName))
                Directory.CreateDirectory(@directoryName);

            string output = @directoryName + Path.DirectorySeparatorChar + fileName;
            bool exists = File.Exists(@output);
            if (exists)
                if (deleteIfExists)
                    File.Delete(@output);
                else
                {
                    LogToFile.WriteWarning("Le fichier éxiste déjà : " + fileName);
                    return;
                }


            try
            {
                // Create an Encoder object based on the GUID for the Compression parameter category
                System.Drawing.Imaging.Encoder objEncoder = System.Drawing.Imaging.Encoder.Compression;
                // create encode parameters
                EncoderParameters encParameters = new EncoderParameters(1);
                EncoderParameter encParameter = new EncoderParameter(objEncoder, (long)EncoderValue.CompressionCCITT4);
                encParameters.Param[0] = encParameter;

                // Jpeg image codec
                using (FileStream fs = new FileStream(@output, FileMode.CreateNew, FileAccess.Write, FileShare.Read))
                {
                    img.Save(fs, jpegCodec, encParameters);
                }
            }
            catch (Exception e)
            {
                LogToFile.WriteException(e, "UtilsLib ImageSave error : " + fileName);
                throw e;
                //return false;
            }
        }

        public static string ImageOverlapByUrl(string ImgSourceURL, string imgLayerURL, string imageDestinationFileName, string imageDestinationPath, int width, int height)
        {
            try
            {
                HttpWebRequest requestSource = (HttpWebRequest)WebRequest.Create(ImgSourceURL);
                WebResponse responseSource = requestSource.GetResponse();
                Image imageSource = System.Drawing.Image.FromStream(responseSource.GetResponseStream());

                HttpWebRequest requestLayer = (HttpWebRequest)WebRequest.Create(imgLayerURL);
                WebResponse responseLayer = requestLayer.GetResponse();
                System.Drawing.Image layerToAdd = System.Drawing.Image.FromStream(responseLayer.GetResponseStream());

                Bitmap layerToAddResized;

                if (width != 0 && height != 0)
                {
                    layerToAddResized = new Bitmap(width, height);
                }
                else
                {
                    layerToAddResized = new Bitmap(imageSource.Width, imageSource.Height);
                }


                using (Graphics g = Graphics.FromImage(layerToAddResized))
                {
                    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    g.SmoothingMode = SmoothingMode.HighQuality;
                    g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    g.CompositingQuality = CompositingQuality.HighQuality;
                    if (width != 0 && height != 0)
                    {
                        g.DrawImage(layerToAdd, 0, 0, width, height);
                    }
                    else
                    {
                        g.DrawImage(layerToAdd, 0, 0, imageSource.Width, imageSource.Height);
                    }
                }

                Image imageFinale;

                if (width != 0 && height != 0)
                {
                    imageFinale = new Bitmap(imageSource, width, height);
                }
                else
                {
                    imageFinale = new Bitmap(imageSource);
                }


                using (Graphics g = Graphics.FromImage(imageFinale))
                {
                    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    g.SmoothingMode = SmoothingMode.HighQuality;
                    g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    g.CompositingQuality = CompositingQuality.HighQuality;
                    g.TextRenderingHint = TextRenderingHint.AntiAlias;
                    g.DrawImage(layerToAddResized, 0, 0);
                }

                imageFinale.Save(imageDestinationPath + imageDestinationFileName + ".jpg", ImageFormat.Jpeg);

                imageSource.Dispose();
                layerToAdd.Dispose();
                imageFinale.Dispose();
                layerToAddResized.Dispose();

                return "OK";
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public static string ImageOverlapByPath(string ImgSourcePath, string imgLayerPath, string imageDestinationFileName, string imageDestinationPath, int width, int height)
        {
            try
            {
                Image imageSource = Image.FromFile(ImgSourcePath);
                Image layerToAdd = Image.FromFile(imgLayerPath);

                Bitmap layerToAddResized;

                if (width != 0 && height != 0)
                {
                    layerToAddResized = new Bitmap(width, height);
                }
                else
                {
                    layerToAddResized = new Bitmap(imageSource.Width, imageSource.Height);
                }


                using (Graphics g = Graphics.FromImage(layerToAddResized))
                {
                    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    g.SmoothingMode = SmoothingMode.HighQuality;
                    g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    g.CompositingQuality = CompositingQuality.HighQuality;
                    if (width != 0 && height != 0)
                    {
                        g.DrawImage(layerToAdd, 0, 0, width, height);
                    }
                    else
                    {
                        g.DrawImage(layerToAdd, 0, 0, imageSource.Width, imageSource.Height);
                    }
                }

                Image imageFinale;

                if (width != 0 && height != 0)
                {
                    imageFinale = new Bitmap(imageSource, width, height);
                }
                else
                {
                    imageFinale = new Bitmap(imageSource);
                }


                using (Graphics g = Graphics.FromImage(imageFinale))
                {
                    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    g.SmoothingMode = SmoothingMode.HighQuality;
                    g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    g.CompositingQuality = CompositingQuality.HighQuality;
                    g.TextRenderingHint = TextRenderingHint.AntiAlias;
                    g.DrawImage(layerToAddResized, 0, 0);
                }

                if (!Directory.Exists(imageDestinationPath))
                    Directory.CreateDirectory(imageDestinationPath);
                imageFinale.Save(imageDestinationPath + imageDestinationFileName + ".jpg", ImageFormat.Jpeg);

                imageSource.Dispose();
                layerToAdd.Dispose();
                imageFinale.Dispose();
                layerToAddResized.Dispose();

                return "OK";
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }


    }
}
